home *** CD-ROM | disk | FTP | other *** search
/ Die Speccy' 97 / Die Speccy' 97.iso / amiga_system / the_aminet / util / arc / untar.lha / untar.c < prev   
C/C++ Source or Header  |  1993-11-12  |  2KB  |  110 lines

  1. /* Un-TAR a Tape ARchive file */
  2. /* By Andrew Church           */
  3. /* 95ACHURCH@vax.mbhs.edu     */
  4.  
  5. #include "stdio.h"
  6. #include "stdlib.h"
  7.  
  8. struct FileHeader {
  9.   int  type;
  10.   long size;
  11.   char name[100];
  12. };
  13.  
  14. FILE *tar,*f;
  15. long pos;
  16. struct FileHeader hdr;
  17.  
  18. void AbsSeek(f,pos)
  19. FILE *f;
  20. long pos;
  21. {
  22.   fsetpos(f,&pos);
  23. }
  24.  
  25. void RelSeek(f,pos)
  26. FILE *f;
  27. long pos;
  28. {
  29.   long a;
  30.  
  31.   fgetpos(f,&a); a+=pos;
  32.   fsetpos(f,&a);
  33. }
  34.  
  35. void CopyData(f1,f2,size)
  36. FILE *f1,*f2;
  37. long size;
  38. {
  39.   char buf[512];
  40.  
  41.   while(size>512) {
  42.     fread(buf,512,1,f1);
  43.     fwrite(buf,512,1,f2);
  44.     size-=512;
  45.   }
  46.   fread(buf,size,1,f1);
  47.   fwrite(buf,size,1,f2);
  48. }
  49.  
  50. long OctalToDec(s)
  51. char *s;
  52. {
  53.   int i;
  54.   long n=0;
  55.  
  56.   for(i=0;i<strlen(s);i++)
  57.     if(s[i]!=' ') {
  58.       n<<=3; n+=s[i]-'0';
  59.     }
  60.   return n;
  61. }
  62.  
  63. void ReadHeader(hdr)
  64. struct FileHeader *hdr;
  65. {
  66.   char s[16];
  67.  
  68.   fread(hdr->name,1,100,tar);
  69.   fread(s,1,8,tar); s[8]=0; hdr->type=OctalToDec(s);
  70.   RelSeek(tar,16);
  71.   fread(s,1,12,tar); s[12]=0; hdr->size=OctalToDec(s);
  72.   RelSeek(tar,376);
  73.   pos+=512;
  74. }
  75.  
  76. int main(argc,argv)
  77. int argc;
  78. char **argv;
  79. {
  80.   if(argc==1) {
  81.     puts("Required argument missing");
  82.     exit(20);
  83.   }
  84.   if(tar=fopen(argv[1],"r")) {
  85.     printf("Extracting files from archive: %s\n",argv[1]);
  86.     pos=0;
  87.     ReadHeader(&hdr);
  88.     while(ftell(tar)!=EOF && hdr.name[0]) {
  89.       if(hdr.name[strlen(hdr.name)-1]=='/') {
  90.         hdr.name[strlen(hdr.name)-1]=0;  /* remove trailing '/' */
  91.         printf("Creating directory %s\n",hdr.name);
  92.         mkdir(hdr.name,0);
  93.       } else {
  94.         if(f=fopen(hdr.name,"w")) {
  95.           printf("Extracting (%8d bytes) %s\n",hdr.size,hdr.name);
  96.           CopyData(tar,f,hdr.size);
  97.           fclose(f);
  98.         }
  99.         pos+=(hdr.size+511) & -512;
  100.         AbsSeek(tar,pos);
  101.       }
  102.       ReadHeader(&hdr);
  103.     }
  104.     fclose(tar);
  105.     exit(0);
  106.   }
  107.   printf("File not found: %s\n",argv[1]);
  108.   exit(20);
  109. }
  110.